#include <stdio.h>

// 写法一
int sum(int arr[], int len);
// 写法二
int sum(int *arr, int len);

int sumByPointerStartAndEnd(int *start, int *end);

void printArray(int *arr, int len);

int main(void)
{
    int a[5] = {11, 22, 33, 44, 55};
    int *p;

    p = &a[0];          // 等同于下面
    p = a;              // 数组名就是数组第一个元素的指针
    printf("%d\n", *p); // 等同于 *(&a[0]),等同于a[0]
    printf("%d\n", *a); // 等同于 *(&a[0]),等同于a[0]

    int total = sum(a, 5);
    printf("%d\n", total);

    int b[2][2] = {{11, 22}, {33, 44}};
    printf("%d\n", *(b[0])); // b[0]是一个一维数组名，是其第一个元素b[0][0]的指针, 等同于&b[0][0]。因此*(b[0])等同于*(&b[0][0])，即为b[0][0]
    // 等同于
    printf("%d\n", **b); // a是其第一个元素（一个一维数组{11,22}）的指针, 等于&b[0], 因此*a解引用后为即b[0], 对b[0]解引用, 跟上一行代码同理

    // 注意，数组名指向的地址是不能更改的
    // 声明数组时，编译器自动为数组分配了内存地址，这个地址与数组名是绑定的，不可更改，下面的代码会报错
    int ints[100];
    // ints = NULL; // 报错

    int c[5] = {1, 2, 3, 4, 5};

    // 写法一
    // int d[5] = c; // 报错

    // 写法二
    int e[5];
    // e = c; // 报错

    int f[5] = {1, 2, 3, 4, 5};
    printArray(f, 5);

    total = sumByPointerStartAndEnd(f, f + 5);
    printf("%d\n", total);

    // 将某个数组成员的地址，减去数组起始地址，就可以知道，当前成员与起始地址之间有多少个成员。
    int g[5] = {20, 10, 5, 39, 88};
    p = g;

    while (*p != 88)
        p++;

    printf("%ld\n", p - g); // 4

    // 对于多维数组，数组指针的加减法对于不同维度，含义是不一样的
    int h[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
    // h + 1 是一个指针，其类型为int (*p)[2], 对其解引用得到是一个一维数组名h[1], h[1]这个一维数组名是其第一个元素h[1][0]的指针, 对其解引用*h[1], 得到的是h[1][0]
    printf("%d\n", **(h + 1));         // 3, 等同于*h[1]
    printf("%d\n", *((*(h + 1)) + 1)); // 4, 等同于*(h[1] + 1)
    printf("%d\n", *h[1]);             // 3
    printf("%d\n", *(h[1] + 1));       // 4
}

int sum(int *arr, int len)
{
    int total = 0;
    for (int i = 0; i < len; i++)
    {
        total += arr[i];
    }
    return total;
}

void printArray(int *arr, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d\t", *(arr + i));
    }
    printf("\n");
}

int sumByPointerStartAndEnd(int *start, int *end)
{
    int total = 0;
    while (start < end)
    {
        total += *(start);
        start++;
    }
    return total;
}